package org.shaka.db.sqlbuilder.sql;

import java.util.List;

import com.google.common.collect.Lists;

public abstract class SqlCondition {
    private List<Value> values;
    private List<Object> params;

    public SqlCondition(Object... params) {
        this.values = Lists.newArrayList();
        this.params = Lists.newArrayList();
        for (Object param : params) {
            Value value = new Value(param);
            if (value.isParam()) {
                this.params.add(value.getValue());
            }
            if (value.isParams()) {
                this.params.addAll(value.getValues());
            }
            this.values.add(value);
        }
    }

    public abstract String conditionsPartial();

    public Value getFirstValue() {
        return getValue(0);
    }

    public Value getValue(int index) {
        return values.get(index);
    }

    public List<Value> getValues() {
        return values;
    }

    public boolean hasParams() {
        return !params.isEmpty();
    }

    public List<Object> getParams() {
        return params;
    }

    public static class Value {
        private String conditionWord;
        private Object value;
        private List<Object> values;
        private final boolean isParam;
        private final boolean isParams;

        public Value(Object value) {
            this.value = value;
            if (value instanceof SqlColumn) {
                SqlColumn column = (SqlColumn) value;
                conditionWord = column.valuePartial();
                isParam = false;
                isParams = false;
            } else if (value instanceof SqlSelect) {
                SqlSelect select = (SqlSelect) value;
                conditionWord = select.buildSql();
                values = select.params();
                isParam = false;
                isParams = (values.size() > 0);
            } else {
                conditionWord = "?";
                isParam = true;
                isParams = false;
            }
        }

        public String getConditionWord() {
            return conditionWord;
        }

        public void setConditionWord(String conditionWord) {
            this.conditionWord = conditionWord;
        }

        public Object getValue() {
            return value;
        }

        public List<Object> getValues() {
            return values;
        }

        public boolean isParams() {
            return isParams;
        }

        public boolean isParam() {
            return isParam;
        }
    }
}
